package com.rzjm.exercise.common.log.aspect;

import java.util.Date;
import java.util.Optional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.rzjm.exercise.common.log.annotation.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.rzjm.exercise.common.log.LogQueue;
import com.rzjm.exercise.common.utils.HttpContextUtils;
import com.rzjm.exercise.common.utils.IPUtils;
import com.rzjm.exercise.common.utils.JSONUtils;
import com.rzjm.exercise.common.utils.NumberUtils;
import com.rzjm.exercise.common.utils.ShiroUtils;
import com.rzjm.exercise.common.utils.StringUtils;
import com.rzjm.exercise.sys.core.log.domain.LogDO;
import com.rzjm.exercise.sys.core.log.service.LogService;
import com.rzjm.exercise.sys.system.user.domain.UserDO;

@Aspect
@Component
public class LogAspect {
    @Resource
    LogService logService;


    @Pointcut("@annotation(com.rzjm.exercise.common.log.annotation.Log)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = point.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //异步保存日志
        saveLog(point, time);
        return result;
    }

    void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        LogDO sysLog = new LogDO();

        Optional.of(signature.getMethod().getAnnotation(Log.class)).ifPresent((syslog) -> {
        	// 注解上的描述
            sysLog.setOperation(syslog.value());
        });

        // 请求的方法名
        sysLog.setMethod(joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()");

        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        sysLog.setParams(StringUtils.substring(JSONUtils.beanToJson(request.getParameterMap()), 0, 499));
        // 设置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));

        // 用户名
        UserDO currUser = ShiroUtils.getUser();
        if (currUser == null) {
        	sysLog.setUserId(-1);
            sysLog.setUsername("获取用户信息为空");
        } else {
            sysLog.setUserId(ShiroUtils.getUserId());
            sysLog.setUsername(ShiroUtils.getUser().getUsername());
        }

        sysLog.setTime(NumberUtils.toInt(time));
        // 系统当前时间
        sysLog.setGmtCreate(new Date());

        LogQueue.INSTANCE.offer(sysLog);
    }
}
